<template>
  <canvas 
    ref="particleCanvas" 
    class="particle-canvas"
    :style="{ opacity: opacity }"
  ></canvas>
</template>

<script>
export default {
  name: 'MouseParticleEffect',
  props: {
    color: {
      type: String,
      default: '#4361ee' // 默认使用主题色
    },
    particleCount: {
      type: Number,
      default: 15
    },
    speed: {
      type: Number,
      default: 0.5
    },
    opacity: {
      type: Number,
      default: 0.6
    },
    size: {
      type: Number,
      default: 3
    }
  },
  data() {
    return {
      ctx: null,
      particles: [],
      mouse: {
        x: null,
        y: null,
        radius: 80 // 鼠标影响范围
      },
      animationId: null,
      lastMousePosition: { x: 0, y: 0 },
      mouseSpeed: 0
    }
  },
  mounted() {
    this.initCanvas();
    this.initEventListeners();
    this.animate();
  },
  beforeUnmount() {
    this.cleanup();
  },
  methods: {
    initCanvas() {
      const canvas = this.$refs.particleCanvas;
      canvas.width = window.innerWidth;
      canvas.height = window.innerHeight;
      this.ctx = canvas.getContext('2d');
      
      // 创建粒子
      for (let i = 0; i < this.particleCount; i++) {
        this.particles.push(this.createParticle());
      }
    },
    
    createParticle(x, y, directionX = 0, directionY = 0, isFromMouse = false) {
      // 随机位置
      const posX = x || Math.random() * window.innerWidth;
      const posY = y || Math.random() * window.innerHeight;
      
      // 大小随机变化一点
      const size = isFromMouse 
        ? this.size + Math.random() * 2 
        : this.size * (0.8 + Math.random() * 0.4);
      
      // 方向和速度
      const dX = directionX || (Math.random() * 2 - 1) * this.speed;
      const dY = directionY || (Math.random() * 2 - 1) * this.speed;
      
      return {
        x: posX,
        y: posY,
        size: size,
        initialSize: size,
        color: this.color,
        directionX: dX,
        directionY: dY,
        life: isFromMouse ? 100 : 200 + Math.random() * 100,
        isFromMouse: isFromMouse
      };
    },
    
    initEventListeners() {
      window.addEventListener('mousemove', this.handleMouseMove);
      window.addEventListener('resize', this.handleResize);
      window.addEventListener('scroll', this.handleScroll);
    },
    
    cleanup() {
      window.removeEventListener('mousemove', this.handleMouseMove);
      window.removeEventListener('resize', this.handleResize);
      window.removeEventListener('scroll', this.handleScroll);
      
      if (this.animationId) {
        cancelAnimationFrame(this.animationId);
      }
    },
    
    handleMouseMove(e) {
      // 计算鼠标速度
      const currentSpeed = Math.sqrt(
        Math.pow(e.clientX - this.lastMousePosition.x, 2) +
        Math.pow(e.clientY - this.lastMousePosition.y, 2)
      );
      
      this.mouseSpeed = currentSpeed;
      this.lastMousePosition = { x: e.clientX, y: e.clientY };
      
      // 更新鼠标位置
      this.mouse.x = e.clientX;
      this.mouse.y = e.clientY;
      
      // 如果鼠标移动速度足够快，创建粒子
      if (currentSpeed > 5) {
        const particleCount = Math.min(Math.floor(currentSpeed / 5), 3);
        for (let i = 0; i < particleCount; i++) {
          // 计算方向 - 基于鼠标移动方向
          const dirX = (e.clientX - this.lastMousePosition.x) * 0.1;
          const dirY = (e.clientY - this.lastMousePosition.y) * 0.1;
          
          this.particles.push(this.createParticle(
            e.clientX + (Math.random() * 20 - 10),
            e.clientY + (Math.random() * 20 - 10),
            dirX * (0.5 + Math.random() * 0.5),
            dirY * (0.5 + Math.random() * 0.5),
            true
          ));
        }
      }
    },
    
    handleResize() {
      const canvas = this.$refs.particleCanvas;
      canvas.width = window.innerWidth;
      canvas.height = window.innerHeight;
    },
    
    handleScroll() {
      // 更新鼠标Y位置，考虑滚动
      if (this.mouse.x && this.mouse.y) {
        this.mouse.y = this.lastMousePosition.y + window.scrollY;
      }
    },
    
    animate() {
      this.animationId = requestAnimationFrame(this.animate);
      this.ctx.clearRect(0, 0, window.innerWidth, window.innerHeight);
      
      for (let i = 0; i < this.particles.length; i++) {
        const p = this.particles[i];
        
        // 绘制粒子
        this.ctx.beginPath();
        this.ctx.arc(p.x, p.y, p.size, 0, Math.PI * 2);
        this.ctx.fillStyle = `${p.color}${Math.floor((p.life / (p.isFromMouse ? 100 : 300)) * 255).toString(16).padStart(2, '0')}`;
        this.ctx.fill();
        
        // 更新位置
        p.x += p.directionX;
        p.y += p.directionY;
        
        // 减少生命值
        p.life--;
        
        // 逐渐缩小
        if (p.life < 50) {
          p.size = p.initialSize * (p.life / 50);
        }
        
        // 如果粒子寿命结束，重置它
        if (p.life <= 0) {
          if (p.isFromMouse) {
            // 移除鼠标生成的粒子
            this.particles.splice(i, 1);
            i--;
          } else {
            // 重置随机漂浮的粒子
            this.particles[i] = this.createParticle();
          }
        }
        
        // 边界检测
        if (p.x < 0 || p.x > window.innerWidth || p.y < 0 || p.y > window.innerHeight) {
          if (p.isFromMouse) {
            // 移除鼠标生成的粒子
            this.particles.splice(i, 1);
            i--;
          } else {
            // 重置随机漂浮的粒子
            this.particles[i] = this.createParticle();
          }
        }
      }
    }
  }
}
</script>

<style scoped>
.particle-canvas {
  position: fixed;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  pointer-events: none;
  z-index: 1000;
}
</style> 